package socket;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

/**
 * 聊天室客户端
 */
public class Client {
    /*
    java.net.Socket;套接字
    Socket封装了TCP协议的通讯细节，使用它可以与远端计算机建立连接
    并使用两个流(一个输入，一个输出)完成与远端计算机的数据交互
     */
    private Socket socket;

    /**
     * 客户端构造方法，用于初始化客户端
     */
    public Client(){

        try {
            /*
            Socket常用构造方法：
            Socket(String host,int port)
            实例化Socket的过程就是与服务端建立连接的过程，如果
            指定的位置找不到服务端则会抛出异常
            参数1：服务端的IP地址信息
            参数2：服务端开启的服务端口
            我们可以通过IP找到网络上服务端所在的计算机，通过端口
            可以连接到该计算机上的服务端应用程序
             */
            System.out.println("正在连接服务端...");
            socket = new Socket("localhost",8088);
            System.out.println("与服务端建立连接!");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void start(){
        try {
            //启动读取服务端消息的线程
            ServerHandler handler =new ServerHandler();
            Thread t = new Thread(handler);
            t.start();
            /*
            Socket提供的方法：
            OutputStream getOutputStream()
            通过socket获取的输出流写出的字节会发送给链接的远端计算机
             */
            OutputStream out = socket.getOutputStream();
            OutputStreamWriter osw = new OutputStreamWriter(out,"UTF-8");
            BufferedWriter bw = new BufferedWriter(osw);
            PrintWriter pw = new PrintWriter(bw,true);

            Scanner scan = new Scanner(System.in);
            while(true){
                String line = scan.nextLine();
                if("exit".equals(line)){
                    break;
                }
                    pw.println(line);
            }


        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            /*
            当不再需要通讯时，应当调用socket的close方法，
            该方法会给远端计算机发送一个断开连接的信号，然后将连接关闭。
             */
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Client client = new Client();
        client.start();
    }

    /**
     * 该线程用于循环读取服务端发送过来的信息
     */
    class ServerHandler implements  Runnable{
        public void run(){
            try{
                InputStream in = socket.getInputStream();
                InputStreamReader isr = new InputStreamReader(in,"UTF-8");
                BufferedReader br = new BufferedReader(isr);

                String line;
                while((line=br.readLine())!=null){
                    System.out.println(line);
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
}
